package com.soup.common.module.sys.api;

import com.google.common.collect.ImmutableMap;
import com.soup.common.constant.CommonConstant;
import com.soup.common.constant.LoginContext;
import com.soup.common.entity.ErrorCode;
import com.soup.common.entity.QueryParam;
import com.soup.common.entity.QueryRequest;
import com.soup.common.entity.Result;
import com.soup.common.exception.auth.AuthException;
import com.soup.common.exception.sys.UserOperationException;
import com.soup.common.module.sys.data.MenuResponse;
import com.soup.common.module.sys.data.ResetpwdRequest;
import com.soup.common.module.sys.data.SetInfoRequest;
import com.soup.common.module.sys.data.UserRequest;
import com.soup.common.module.sys.entity.User;
import com.soup.common.module.sys.service.MenuService;
import com.soup.common.module.sys.service.UserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;

/**
 * 系统用户 api
 *
 * @author zhaoyi
 */
@RestController
@RequestMapping("/user")
public class UserApi {

    @Resource
    private UserService userService;

    @Autowired
    private MenuService menuService;

    @Value("${user.defaultPwd}")
    private String defaultPwd;

    /**
     * 分页查询系统用户
     *
     * @param queryParam 分页查询参数
     * @return 分页结果
     */
    @GetMapping
    public Result page(@Valid QueryRequest queryParam) {
        return userService.page(queryParam);
    }

    /**
     * 新增系统用户
     *
     * @param userRequest 用户新增入参
     * @return 操作结果
     */
    @PostMapping
    public int add(@RequestBody @Valid UserRequest userRequest) {
        // 登录名称不能重复
        int countByLoginName = userService.countByEqual(ImmutableMap.of("loginName", userRequest.getLoginName()));
        if (countByLoginName > CommonConstant.NUM_0) {
            throw new UserOperationException(ErrorCode.USER_LOGINNAME_EXSITED);
        }

        User user = new User();
        BeanUtils.copyProperties(userRequest, user);
        if (StringUtils.isEmpty(user.getPassword())) {
            user.setPassword(defaultPwd);
        }
        user.setNickName(user.getLoginName());
        user.setDeleted(CommonConstant.NOT_DELETED);
        user.setGmtCreate(new Date());

        return userService.save(user);
    }

    /**
     * 删除用户
     */
    @DeleteMapping("/{userId}")
    public int delete(@PathVariable int userId) {
        User user = userService.selectByKey(userId);
        if (null == user) {
            throw new UserOperationException(ErrorCode.USER_NOT_FOUND);
        }

        // 默认用户无法删除
        if (user.getId() == CommonConstant.NUM_1) {
            throw new UserOperationException(ErrorCode.USER_DEL_NOT_SUPPORT);
        }

        user.setDeleted(CommonConstant.DELETED);
        user.setGmtModified(new Date());
        return userService.updateNotNull(user);
    }

    /**
     * 修改用户
     */
    @PutMapping("/{userId}")
    public int edit(@PathVariable int userId, @RequestBody User user) {
        User tempUser = userService.selectByKey(userId);
        if (null == tempUser) {
            throw new UserOperationException(ErrorCode.USER_NOT_FOUND);
        }
        // 判断登录名称是否已经存在
        QueryParam queryParam = new QueryParam(User.class);
        QueryParam.Criteria criteria = queryParam.createCriteria();
        criteria.andEqualTo("loginName", user.getLoginName());
        criteria.andNotEqualTo("id", userId);
        List<User> users = userService.selectByQueryParam(queryParam);
        if (CollectionUtils.isNotEmpty(users)) {
            throw new UserOperationException(ErrorCode.USER_LOGINNAME_EXSITED);
        }

        user.setId(userId);
        user.setGmtModified(new Date());
        return userService.updateNotNull(user);
    }

    /**
     * 重置密码
     */
    @PutMapping("/{userId}/resetpwd")
    public int resetpwd(@PathVariable Integer userId) {
        User user = userService.selectByKey(userId);
        if (null == user) {
            throw new UserOperationException(ErrorCode.USER_NOT_FOUND);
        }

        user.setPassword(defaultPwd);
        user.setGmtModified(new Date());
        return userService.updateNotNull(user);
    }

    /**
     * 查询当前登录用户的信息
     */
    @GetMapping("/userinfo")
    public User findById() {
        // 当前登录用户
        return LoginContext.LOGIN_USER.get();
    }

    /**
     * 查询登录用户的菜单列表
     */
    @GetMapping("/menus")
    public List<MenuResponse> userMenu() {
        return menuService.getLoginUserMenus();
    }

    /**
     * 修改当前登录用户的密码
     */
    @PutMapping("/resetpwd")
    public int resetpwd(@RequestBody @Valid ResetpwdRequest resetpwdRequest) {
        // 当前登录用户
        User user = LoginContext.LOGIN_USER.get();
        if (!StringUtils.equals(user.getPassword(), resetpwdRequest.getOldPassword())) {
            throw new AuthException(ErrorCode.USER_PASSWORD_ERROR);
        }
        if (!StringUtils.equals(resetpwdRequest.getPassword(), resetpwdRequest.getRepassword())) {
            throw new AuthException(ErrorCode.USER_PASSWORD_INCONFORMITY);
        }
        user.setPassword(resetpwdRequest.getPassword());
        user.setGmtModified(new Date());
        return userService.updateNotNull(user);
    }

    /**
     * 修改当前登录用户的信息
     */
    @PutMapping("/setinfo")
    public int setInfo(@RequestBody @Valid SetInfoRequest setInfoRequest) {
        User user = LoginContext.LOGIN_USER.get();
        BeanUtils.copyProperties(setInfoRequest, user);
        return userService.updateNotNull(user);
    }
}
